#include "thread_pool.hpp"
void *threadFunc(void *arg)
{
    threadpool_t *threadpool = (threadpool_t *)arg;
    while (1)
    {
        task_t *ptask = taskDequeue(&threadpool->queue);
        if (ptask)
        {
            doTask(ptask);
            free(ptask);
        }
        else
        {
            break;
        }
    }
    printf("sub thread %ld is exiting.\n", pthread_self());
    return nullptr;
}
void threadpoolInit(threadpool_t *threadpool, int num)
{
    if (threadpool)
    {
        threadpool->pthreads = (pthread_t *)calloc(num, sizeof(pthread_t));
        threadpool->threadNum = num;
        queueInit(&threadpool->queue);
    }
}
void threadpoolDestroy(threadpool_t *threadpool)
{
    if (threadpool)
    {
        free(threadpool->pthreads);
        queueDestroy(&threadpool->queue);
    }
}
void threadpoolStart(threadpool_t *threadpool)
{
    if (threadpool)
    {
        for (int i = 0; i < threadpool->threadNum; ++i)
        {
            int ret = pthread_create(
                &threadpool->pthreads[i],
                NULL,
                threadFunc,
                threadpool);
            THREAD_ERROR_CHECK(ret, "pthread_create");
            printf("sub thread %ld \n", threadpool->pthreads[i]);
        }
    }
}
void broadcastAll(task_queue_t *que)
{
    que->exit_flag = 1;
    pthread_cond_broadcast((&que->cond));
}
void threadpoolStop(threadpool_t *threadpool)
{
    while (!queueIsEmpty(&threadpool->queue))
    {
        sleep(1);
    }
    broadcastAll(&threadpool->queue);
    for (int i = 0; i < threadpool->threadNum; i++)
    {
        pthread_join(threadpool->pthreads[i], nullptr);
    }
}